@thallylabs/migrate 0.2.7 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,12 +49,38 @@ computes redirects dynamically and can't be evaluated statically, so its
49
49
  presence is reported with a warning instead of being silently ignored. A
50
50
  static `--ifm-color-primary` accent color in the classic theme's `customCss`
51
51
  file is imported the same way Mintlify's and Fern's theme colors are.
52
+ Versioned docs under `versioned_docs/` and translated docs under
53
+ `i18n/<locale>/docusaurus-plugin-content-docs/` are imported with their
54
+ navigation, including locale-prefixed routes such as `/fr/...`. Each version
55
+ and locale keeps its own route tree; sidebar entries without source documents
56
+ are reported.
57
+ Docusaurus heading ID comments such as `{/* #custom-id */}` become explicit
58
+ HTML anchors so links to those headings keep working after migration. Links
59
+ using Docusaurus' implicit heading slugs also get explicit aliases when the
60
+ linked heading or option-table field can be matched uniquely. Repeated option
61
+ fields use the nearest preceding row when all local references agree;
62
+ otherwise ambiguous anchors remain warnings.
63
+ Longer fenced code examples keep nested shorter fences inert. An archived
64
+ admonition missing its closing delimiter is closed before the next top-level
65
+ heading (or at the end of the page) so its remaining content stays importable.
66
+ Docusaurus `mdx-code-block` wrappers are opened as live MDX when the resulting
67
+ page compiles and its special fences contain no module declarations. Pages
68
+ whose fragments still need Docusaurus theme imports or remark plugins remain
69
+ fenced and are retained.
52
70
 
53
71
  Fern repositories are located by their `fern/docs.yml` + `fern/fern.config.json`
54
72
  pair. `docs.yml` is parsed as bounded YAML—never executed—and preserves tabs,
55
73
  nested sections (including `slug`/`skip-slug`), navbar links, redirects, the
56
74
  default Fern version's navigation, and theme accent colors. Only pages
57
75
  referenced from `docs.yml` are imported, matching Fern's own publishing model.
76
+ Versioned `folder:` entries expand the Markdown files they contain, even when
77
+ the folder or an individual page is outside `fern/` but still inside the
78
+ checkout. An explicit empty tab `slug` keeps pages at the site root; a folder
79
+ title changes its navigation label without changing its directory-based URL.
80
+ Internal links are adjusted for the site's domain path, selected version, and
81
+ source-file routes. Links to sections not imported into Thally stay on the
82
+ published Fern site and produce a migration warning, so the generated site can
83
+ build while the remaining content is moved separately.
58
84
  Every `api:` section's OpenAPI document is resolved from its own
59
85
  `generators.yml` (`api.specs[].openapi`, or the legacy `api:` string) and
60
86
  imported into its own tab — a docs.yml with several API sections (e.g. a REST
@@ -112,8 +138,16 @@ The importer creates a root redirect to the first available page in source
112
138
  navigation when no root introduction exists, while retaining a separate custom
113
139
  homepage and explicit redirects. Locale tags and recognized locale-prefixed
114
140
  sections are normalized without discarding original URL redirects.
141
+ Mintlify's generated `param-*` links for settings headings and named fields
142
+ become explicit anchors in migrated MDX.
115
143
 
116
144
  Simple interactive HTML blocks in MDX are extracted into client components.
145
+ For a copied client component that receives a simple page-authored JSX callback,
146
+ the importer moves the callback into a client wrapper and keeps the page. If
147
+ the callback cannot be moved safely, it keeps the page and the control's child
148
+ content as a passive fallback, with a warning identifying the control. A
149
+ stateful local snippet component is kept as a client component instead of
150
+ flattening away its hooks and state.
117
151
  The Mintlify `search-bar-entry` click trigger is mapped to Thally's search
118
152
  shortcut. Markdown mixed inside interactive JSX, computed imports, and
119
153
  namespace imports are reported for manual review; unsupported source is
@@ -135,11 +169,9 @@ overrun), with a warning naming the page and the component. Packages the starter
135
169
  kept as-is (except `react-dom/server`, whose string renderers throw under
136
170
  Next) and copied into any extracted client module. A source site's own
137
171
  `@/…` path aliases are treated like an unavailable package. A page that
138
- passes a page-authored function (including a class, or a function written as
139
- children) as a prop into a component confirmed to cross the server/client boundary (one this
140
- importer extracted as a client module, or a Thally runtime built-in already
141
- backed by one, such as `Accordion`/`Panel`/`Tabs`) is excluded the same way;
142
- an unconfirmed target is warned instead of dropped.
172
+ passes a page-authored function into a client component needs the client
173
+ wrapper described above; unsupported callback shapes retain their content
174
+ with a warning. An unconfirmed target is warned for review.
143
175
  File paths cannot escape the repository checkout; symlinks and oversized
144
176
  graphs are rejected. This is compatibility analysis, **not a code sandbox**:
145
177
  imported JavaScript executes when the developer builds or runs the resulting
package/dist/index.d.ts CHANGED
@@ -41,13 +41,23 @@ interface MigrationNavbarConfig {
41
41
  href: string;
42
42
  type?: 'github';
43
43
  }>;
44
+ /** Explicit null suppresses the starter's sample call to action. */
44
45
  primary?: {
45
46
  label: string;
46
47
  href: string;
48
+ } | null;
49
+ /** Local public assets used until an owner uploads a brand replacement. */
50
+ logo?: {
51
+ light: string;
52
+ dark?: string;
53
+ showTitle?: boolean;
54
+ rightText?: string;
47
55
  };
48
56
  }
49
57
  interface MigrationFooterConfig {
50
58
  socials?: Record<string, string>;
59
+ /** Literal footer attribution; `{year}` is resolved by the site at render time. */
60
+ copyright?: string;
51
61
  links?: Array<{
52
62
  heading: string;
53
63
  items: Array<{
@@ -72,6 +82,10 @@ interface MigrationDocsConfig {
72
82
  };
73
83
  banner?: MigrationBannerConfig;
74
84
  navbar?: MigrationNavbarConfig;
85
+ favicon?: {
86
+ light: string;
87
+ dark?: string;
88
+ };
75
89
  footer?: MigrationFooterConfig;
76
90
  seo?: {
77
91
  indexing?: 'navigable' | 'all';
@@ -111,6 +125,8 @@ interface MigrationDocsConfig {
111
125
  code: string;
112
126
  label: string;
113
127
  }>;
128
+ /** Source-authored navigation labels and ordering for each translation. */
129
+ navigation?: Record<string, Array<MigrationNavigationTab>>;
114
130
  };
115
131
  }
116
132
  interface MigrationPage {
@@ -122,6 +138,8 @@ interface MigrationPage {
122
138
  title: string;
123
139
  navTitle?: string;
124
140
  description: string;
141
+ /** Keep SEO/search description without repeating it above Docusaurus body copy. */
142
+ descriptionPlacement?: 'body';
125
143
  badge?: string;
126
144
  keywords: Array<string>;
127
145
  mode?: 'default' | 'wide' | 'custom' | 'center' | 'home';
@@ -221,6 +239,8 @@ interface RepositoryMigrationOptions {
221
239
  docusaurusSkipPlugins?: boolean;
222
240
  /** @internal Additional docs plugins default to autogenerated navigation. */
223
241
  docusaurusSkipSidebar?: boolean;
242
+ /** @internal A version's sidebar is parsed as static data. */
243
+ docusaurusSidebarPath?: string;
224
244
  /** @internal Static assets are shared across docs-plugin instances. */
225
245
  docusaurusSkipAssets?: boolean;
226
246
  /** @internal Redirects are global config, read once, not per plugin instance. */
@@ -310,6 +330,10 @@ interface FernPageDescriptor {
310
330
  /** Path to the referenced page file, relative to the Fern root. */
311
331
  sourcePath: string;
312
332
  navigationId: string;
333
+ /** Fern's sidebar label can intentionally differ from the page title. */
334
+ navTitle?: string;
335
+ /** Keep routable pages excluded by Fern's `hidden` navigation flag. */
336
+ hidden?: boolean;
313
337
  }
314
338
  /** One `api:` navigation node, resolved to the name/tab Thally needs to bind its spec. */
315
339
  interface FernApiSection {
@@ -335,6 +359,11 @@ interface FernNavigationResult {
335
359
  warnings: Array<MigrationWarning>;
336
360
  /** Every `api:` node found in navigation, in document order. A repo can declare several (e.g. a REST and a WebSocket API in separate tabs). */
337
361
  apiSections: Array<FernApiSection>;
362
+ /** Fern changelog tabs render their entries as a feed at the bare route. */
363
+ changelogIndexes: Array<{
364
+ route: string;
365
+ entries: Array<string>;
366
+ }>;
338
367
  }
339
368
  /** Read `fern/docs.yml` without executing anything. */
340
369
  declare function readFernConfig(fernRoot: string): {
@@ -345,6 +374,7 @@ declare function readFernConfig(fernRoot: string): {
345
374
  declare function projectFernNavigation(input: {
346
375
  config: Record<string, unknown>;
347
376
  fernRoot: string;
377
+ repositoryRoot?: string;
348
378
  }): FernNavigationResult;
349
379
 
350
380
  /** Markdown/MDX normalization that preserves every component Thally supports. */
@@ -355,7 +385,7 @@ interface MarkdownPageIdentity {
355
385
  locale?: string;
356
386
  }
357
387
  /** Normalize only syntax Thally cannot render; supported source JSX stays intact. */
358
- declare function normalizeMdx(body: string, platform?: MigrationPlatform): string;
388
+ declare function normalizeMdx(body: string, platform?: MigrationPlatform, unwrapMdxCodeBlocks?: boolean): string;
359
389
  /** Parse source Markdown or MDX into the canonical page representation. */
360
390
  declare function parseMarkdownPage(input: {
361
391
  id: string;